<!DOCTYPE html>
<html
  lang="en"
  xmlns:og="http://ogp.me/ns#"
  xmlns:fb="https://www.facebook.com/2008/fbml"
>
  <head>
    <meta charset="utf-8" />
    <title>PNotify</title>
    <meta name="HandheldFriendly" content="true" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="JavaScript notification plugin." />
    <meta property="og:title" content="PNotify" />
    <meta property="og:type" content="website" />
    <meta property="og:url" content="https://sciactive.com/pnotify/" />
    <meta property="og:image" content="includes/logo.png" />
    <meta property="og:site_name" content="PNotify" />
    <meta property="fb:admins" content="508999194" />
    <meta property="og:description" content="JavaScript notification plugin." />

    <link
      rel="apple-touch-icon"
      sizes="180x180"
      href="includes/favicon/apple-touch-icon.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="32x32"
      href="includes/favicon/favicon-32x32.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="16x16"
      href="includes/favicon/favicon-16x16.png"
    />

    <!-- Dev Notice -->
    <link href="devnote.css" rel="stylesheet" />

    <!-- Page Style -->
    <link href="includes/style.css" rel="stylesheet" />

    <!-- Animate.css -->
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/animate.css@3.7.2/animate.min.css"
      integrity="sha256-PHcOkPmOshsMBC+vtJdVr5Mwb7r0LkSVJPlPrp/IMpU="
      crossorigin="anonymous"
    />

    <!-- NonBlock.js -->
    <script
      src="https://cdn.jsdelivr.net/npm/nonblockjs@1.0.8/NonBlock.es5.js"
      integrity="sha256-ya57jZves9vI0hPcq0IoJMrIuwwk9w01CvkvG5xJQ1s="
      crossorigin="anonymous"
    ></script>

    <!-- Bootstrap -->
    <link
      id="bootstrap-light"
      media="(prefers-color-scheme: no-preference), (prefers-color-scheme: light)"
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css"
      integrity="sha256-L/W5Wfqfa0sdBNIKN9cG6QA5F2qx4qICmU2VgLruv9Y="
      crossorigin="anonymous"
    />
    <link
      id="bootstrap-dark"
      media="(prefers-color-scheme: dark)"
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootswatch@4.4.1/dist/darkly/bootstrap.min.css"
      integrity="sha256-WzKrnqJMmUZVHL8Im0hFLIOJ3UiQtgwK7zNfwxb5Bx0="
      crossorigin="anonymous"
    />
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap.native@2.0.27/dist/bootstrap-native-v4.min.js"
      integrity="sha256-k5gE8gnbCCVtz/4z2LzbAIpMdH8K1Bjl4cTCjm6SZS8="
      crossorigin="anonymous"
    ></script>

    <!-- FontAwesome -->
    <script
      src="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/js/all.min.js"
      integrity="sha256-KzZiKy0DWYsnwMF+X1DvQngQ2/FxF7MF3Ff72XcpuPs="
      crossorigin="anonymous"
    ></script>

    <!-- Material Design Icons Font -->
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/material-icons-font@2.0.0/material-icons-font.css"
      integrity="sha256-Qhft8mGp8dJ8oc6Pvys+NmBL6Mvi4Jqg+T0aN2huMUw="
      crossorigin="anonymous"
    />

    <!-- Roboto Font -->
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap"
      crossorigin="anonymous"
    />

    <!-- JavaScript Source Formatting -->
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/highlight.js@9.18.0/styles/atom-one-dark.css"
      integrity="sha256-k5IP6hFowt2ISQDOHTuCLFciixzxZ/8/qYTlEvTQ6CI="
      crossorigin="anonymous"
    />
    <script
      src="https://cdn.jsdelivr.net/npm/highlight.js@9.18.0/lib/highlight.js"
      integrity="sha256-X93pzXSFftQ1a7EIBCLb8DgWcfcBOlgCwkNQoKKNf2k="
      crossorigin="anonymous"
    ></script>
    <script type="text/javascript">
      module = {};
    </script>
    <script
      src="https://cdn.jsdelivr.net/npm/highlight.js@9.18.0/lib/languages/javascript.js"
      integrity="sha256-gw54feyfS2axM9wJn/Yw66WD7HEb8LnC1F6M2D3Hkd8="
      crossorigin="anonymous"
    ></script>
    <script type="text/javascript">
      hljs.registerLanguage('javascript', module.exports);
      delete module;
    </script>
    <script type="text/javascript">
      module = {};
    </script>
    <script
      src="https://cdn.jsdelivr.net/npm/highlight.js@9.18.0/lib/languages/css.js"
      integrity="sha256-3HiVmBMOhajA6zBBiKBpQnd28r+GAKg5LBiF63OiQA4="
      crossorigin="anonymous"
    ></script>
    <script type="text/javascript">
      hljs.registerLanguage('css', module.exports);
      delete module;
    </script>
    <script
      src="https://cdn.jsdelivr.net/npm/js-beautify@1.10.3/js/lib/beautifier.min.js"
      integrity="sha256-mtOFRa0v4H67G1yfvpq8Y9olqgFzvOdVvVjaJ7SZF5g="
      crossorigin="anonymous"
    ></script>

    <!-- PNotify CSS -->
    <link rel="stylesheet" href="packages/core/dist/PNotify.css" />
    <link rel="stylesheet" href="packages/core/dist/BrightTheme.css" />
    <link rel="stylesheet" href="packages/core/dist/Material.css" />
    <link rel="stylesheet" href="packages/core/dist/Angeler.css" />
    <link
      rel="stylesheet"
      href="packages/bootstrap4/dist/PNotifyBootstrap4.css"
    />
    <link rel="stylesheet" href="packages/mobile/dist/PNotifyMobile.css" />
    <link rel="stylesheet" href="packages/desktop/dist/PNotifyDesktop.css" />
    <link rel="stylesheet" href="packages/confirm/dist/PNotifyConfirm.css" />
    <link
      rel="stylesheet"
      href="packages/countdown/dist/PNotifyCountdown.css"
    />
    <link rel="stylesheet" href="packages/paginate/dist/PNotifyPaginate.css" />
    <link
      rel="stylesheet"
      href="packages/reference/dist/PNotifyReference.css"
    />

    <!-- PNotify JS -->
    <script src="packages/core/dist/PNotify.js"></script>
    <script src="packages/bootstrap4/dist/PNotifyBootstrap4.js"></script>
    <script src="packages/font-awesome5-fix/dist/PNotifyFontAwesome5Fix.js"></script>
    <script src="packages/font-awesome5/dist/PNotifyFontAwesome5.js"></script>
    <script src="packages/animate/dist/PNotifyAnimate.js"></script>
    <script src="packages/mobile/dist/PNotifyMobile.js"></script>
    <script src="packages/desktop/dist/PNotifyDesktop.js"></script>
    <script src="packages/confirm/dist/PNotifyConfirm.js"></script>
    <script src="packages/countdown/dist/PNotifyCountdown.js"></script>
    <script src="packages/paginate/dist/PNotifyPaginate.js"></script>
    <script src="packages/reference/dist/PNotifyReference.js"></script>

    <!-- Custom Styling -->
    <style type="text/css">
      /* Translucent notice CSS */
      [data-pnotify].pnotify.translucent.pnotify-fade-in {
        opacity: 0.8;
      }

      /* Custom styled notice CSS */
      [data-pnotify].custom-elem {
        font-family: Arial, Helvetica, sans-serif;
        font-size: 10pt;
        line-height: 1.1;
      }
      [data-pnotify] .custom-container {
        background-color: #404040;
        background-image: none;
        border: none;
        -moz-border-radius: 10px;
        -webkit-border-radius: 10px;
        border-radius: 10px;
        padding: 15px;
        font-size: 15px;
      }
      [data-pnotify] .custom-title,
      [data-pnotify] .custom-text {
        margin-left: 50px;
        color: #fff;
      }
      [data-pnotify] .custom-title {
        font-weight: bold;
        font-size: 15px;
      }
      [data-pnotify] .custom-icon {
        color: #ffa;
      }

      /* Browser bar stacks. */
      [data-pnotify].pnotify.stack-bar-top {
        width: 100%;
        border-radius: 0;
      }
      [data-pnotify].pnotify.stack-bar-bottom {
        width: 70%;
        border-radius: 0;
      }

      /* Unpositioned notices margin. */
      #unpositioned-context > * {
        margin-bottom: 1em;
      }
    </style>

    <!-- Demo Code -->
    <script type="text/javascript">
      window.addEventListener('DOMContentLoaded', () => {
        // ---
        // Set defaults.
        // ---
        PNotify.defaults.destroy = false;
        PNotify.defaultModules.set(PNotifyMobile, {});
        PNotify.defaultModules.set(PNotifyFontAwesome5Fix, {});

        // ---
        // Notice that opens when the page opens.
        // ---
        PNotify.notice({
          title: 'PNotify',
          text: 'Welcome to the demo site. Try our fresh demos.',
        });
      });
    </script>
  </head>
  <body
    data-spy="scroll"
    data-target=".navbar"
    data-offset="0"
    style="position: relative"
  >
    <nav class="navbar sticky-top navbar-expand-lg navbar-light bg-light">
      <div class="container">
        <a class="navbar-brand" href="https://sciactive.com/pnotify/"
          >PNotify</a
        >
        <button
          class="navbar-toggler"
          type="button"
          data-toggle="collapse"
          data-target="#navbarSupportedContent"
          aria-controls="navbarSupportedContent"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span class="navbar-toggler-icon"></span>
        </button>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item">
              <a class="nav-link" href="#overview">Overview</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#demos-core">Core Demos</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#demos-modules">Module Demos</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#stacks">Stacks</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#comments">Comments</a>
            </li>
          </ul>
          <ul class="navbar-nav">
            <li class="nav-item">
              <a
                class="nav-link"
                href="https://github.com/sciactive/pnotify"
                title="Fork me on GitHub"
                ><i class="fab fa-github"></i
              ></a>
            </li>
            <li class="nav-item">
              <a
                class="nav-link"
                href="https://twitter.com/sciactive"
                title="Follow me on Twitter"
                ><i class="fab fa-twitter"></i
              ></a>
            </li>
            <li class="nav-item dropdown">
              <a
                class="nav-link dropdown-toggle"
                href="#"
                id="navbarDropdown"
                role="button"
                data-toggle="dropdown"
                aria-haspopup="true"
                aria-expanded="false"
              >
                Beyond PNotify
              </a>
              <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                <a
                  class="dropdown-item"
                  href="https://github.com/sciactive/"
                  target="_blank"
                  >SciActive</a
                >
                <div class="dropdown-divider"></div>
                <a
                  class="dropdown-item"
                  href="https://nymph.io/"
                  target="_blank"
                  >Nymph</a
                >
                <a
                  class="dropdown-item"
                  href="https://sveltematerialui.com/"
                  target="_blank"
                  >Svelte Material UI</a
                >
                <a
                  class="dropdown-item"
                  href="https://tunnelgram.com/"
                  target="_blank"
                  >Tunnelgram</a
                >
                <a
                  class="dropdown-item"
                  href="https://sciactive.com/pform/"
                  target="_blank"
                  >PForm</a
                >
                <a
                  class="dropdown-item"
                  href="https://hookphp.org/"
                  target="_blank"
                  >HookPHP</a
                >
              </div>
            </li>
          </ul>
        </div>
      </div>
    </nav>

    <section class="container page-banner" id="overview">
      <h1><img src="includes/logo.png" alt="PNotify" id="logo" /></h1>
      <p id="description">Beautiful notifications and prompts.</p>
      <p class="dev-note" style="display: none">
        You probably want to go to the
        <a href="https://sciactive.com/pnotify/">production site</a>, cause
        things will be broken here.
      </p>
      <div class="row align-items-stretch">
        <div class="col-md-4 my-3">
          <div class="card" style="height: 100%">
            <h5 class="card-header">
              <i class="fas fa-mobile"></i> Mobile Ready
            </h5>
            <div class="card-body">
              PNotify works on your phone and tablet. You can swipe notices away
              to dismiss them.
            </div>
          </div>
        </div>
        <div class="col-md-4 my-3">
          <div class="card" style="height: 100%">
            <h5 class="card-header">
              <i class="fas fa-asterisk"></i> Unobtrusive
            </h5>
            <div class="card-body">
              PNotify uses the
              <a
                href="https://sciactive.com/2020/02/11/the-modalish-notification-flow/"
                target="_blank"
                >modalish notification flow</a
              >
              to provide unobtrusive support for many notifications at once.
            </div>
          </div>
        </div>
        <div class="col-md-4 my-3">
          <div class="card" style="height: 100%">
            <h5 class="card-header"><i class="fas fa-gift"></i> Open Source</h5>
            <div class="card-body">
              PNotify is distributed under the permissive
              <a
                href="http://www.apache.org/licenses/LICENSE-2.0"
                target="_blank"
                >Apache License, Version 2.0</a
              >.
            </div>
          </div>
        </div>
      </div>
      <div class="text-md-right">
        <a
          class="btn btn-primary btn-lg"
          href="https://github.com/sciactive/pnotify/blob/master/README.md#getting-started"
          >Get Started with PNotify</a
        >
      </div>
      <div
        class="dev-note"
        style="
          display: none;
          position: fixed;
          z-index: -1;
          bottom: 20px;
          left: 20px;
          opacity: 0.4;
        "
      >
        <div class="alert alert-danger">
          <h5 style="margin-top: 0">
            <i class="fas fa-exclamation-triangle"></i> Caution warning danger
            attention!
          </h5>
          <p class="mb-0">
            This is the development site. It demos bleeding edge features that
            may not work.
          </p>
        </div>
      </div>
    </section>

    <div id="demos-core" class="container page-section">
      <div class="my-3">
        <h2>
          Simple Demos
          <small>These demos only use core PNotify features.</small>
        </h2>
        <hr />
      </div>
      <div class="card border-dark">
        <h5 class="card-header bg-dark text-white">Choose the Styling</h5>
        <div class="card-body">
          PNotify supports multiple styling methods, icon sets, and display
          modes.

          <div class="my-1">
            <div class="form-check form-check-inline">
              <input
                class="form-check-input"
                type="radio"
                name="styling"
                id="style-brighttheme"
                autocomplete="off"
                checked
              />
              <label class="form-check-label" for="style-brighttheme"
                >Bright Theme</label
              >
            </div>
            <div class="form-check form-check-inline">
              <input
                class="form-check-input"
                type="radio"
                name="styling"
                id="style-material"
                autocomplete="off"
              />
              <label class="form-check-label" for="style-material"
                >Material</label
              >
            </div>
            <div class="form-check form-check-inline">
              <input
                class="form-check-input"
                type="radio"
                name="styling"
                id="style-angeler"
                autocomplete="off"
              />
              <label class="form-check-label" for="style-angeler"
                >Angeler</label
              >
            </div>
            <div class="form-check form-check-inline">
              <input
                class="form-check-input"
                type="radio"
                name="styling"
                id="style-angeler-extended"
                autocomplete="off"
              />
              <label class="form-check-label" for="style-angeler-extended"
                >Angeler (Extended)</label
              >
            </div>
            <div class="form-check form-check-inline">
              <input
                class="form-check-input"
                type="radio"
                name="styling"
                id="style-bootstrap4"
                autocomplete="off"
              />
              <label class="form-check-label" for="style-bootstrap4"
                >Bootstrap</label
              >
            </div>
          </div>

          <div class="my-1">
            <div class="form-check form-check-inline">
              <input
                class="form-check-input"
                type="radio"
                name="mode"
                id="mode-no-preference"
                autocomplete="off"
                checked
              />
              <label class="form-check-label" for="mode-no-preference"
                >System Default</label
              >
            </div>
            <div class="form-check form-check-inline">
              <input
                class="form-check-input"
                type="radio"
                name="mode"
                id="mode-light"
                autocomplete="off"
              />
              <label class="form-check-label" for="mode-light">Light</label>
            </div>
            <div class="form-check form-check-inline">
              <input
                class="form-check-input"
                type="radio"
                name="mode"
                id="mode-dark"
                autocomplete="off"
              />
              <label class="form-check-label" for="mode-dark">Dark</label>
            </div>
          </div>

          <a class="btn btn-info my-1" href="demo/styling.html" target="_blank"
            >Demo All Styles/Icons</a
          >
        </div>
        <script type="text/javascript">
          window.addEventListener('DOMContentLoaded', () => {
            document
              .getElementById('style-brighttheme')
              .addEventListener('change', (e) => {
                PNotify.defaultModules.delete(PNotifyBootstrap4);
                PNotify.defaultModules.delete(PNotifyFontAwesome5);
                PNotify.defaults.styling = 'brighttheme';
                PNotify.defaults.icons = 'brighttheme';
                PNotify.defaults.addClass = '';
                PNotify.defaults.closerHover = true;
                PNotify.notice({
                  title: 'Styling Change',
                  text: 'From now on, notices will be styled with Bright Theme, the default theme.',
                });
              });

            document
              .getElementById('style-material')
              .addEventListener('change', (e) => {
                PNotify.defaultModules.delete(PNotifyBootstrap4);
                PNotify.defaultModules.delete(PNotifyFontAwesome5);
                PNotify.defaults.styling = 'material';
                PNotify.defaults.icons = 'material';
                PNotify.defaults.addClass = '';
                PNotify.defaults.closerHover = true;
                PNotify.notice({
                  title: 'Styling Change',
                  text: 'From now on, notices will be styled with Material.',
                });
              });

            document
              .getElementById('style-angeler')
              .addEventListener('change', (e) => {
                PNotify.defaultModules.delete(PNotifyBootstrap4);
                PNotify.defaultModules.delete(PNotifyFontAwesome5);
                PNotify.defaults.styling = 'angeler';
                PNotify.defaults.icons = 'angeler';
                PNotify.defaults.addClass = '';
                PNotify.defaults.closerHover = false;
                PNotify.notice({
                  title: 'Styling Change',
                  text: 'From now on, notices will be styled with Angeler. They will also always show the closer button, which is how Angela designed it.',
                });
              });

            document
              .getElementById('style-angeler-extended')
              .addEventListener('change', (e) => {
                PNotify.defaultModules.delete(PNotifyBootstrap4);
                PNotify.defaultModules.delete(PNotifyFontAwesome5);
                PNotify.defaults.styling = 'angeler';
                PNotify.defaults.icons = 'angeler';
                PNotify.defaults.addClass = 'angeler-extended';
                PNotify.defaults.closerHover = false;
                PNotify.notice({
                  title: 'Styling Change',
                  text: 'From now on, notices will be styled with Angeler, and use the extended variant. They will also always show the closer button, which is how Angela designed it.',
                });
              });

            document
              .getElementById('style-bootstrap4')
              .addEventListener('change', (e) => {
                PNotify.defaultModules.set(PNotifyBootstrap4, {});
                PNotify.defaultModules.set(PNotifyFontAwesome5, {});
                PNotify.defaults.addClass = '';
                PNotify.defaults.closerHover = true;
                PNotify.notice({
                  title: 'Styling Change',
                  text: 'From now on, notices will be styled with Bootstrap 4 w/ Font Awesome 5 Icons.',
                });
              });

            document
              .getElementById('mode-no-preference')
              .addEventListener('change', (e) => {
                PNotify.defaults.mode = 'no-preference';
                document.getElementById(
                  'bootstrap-light'
                ).attributes.media.value =
                  '(prefers-color-scheme: no-preference), (prefers-color-scheme: light)';
                document.getElementById(
                  'bootstrap-dark'
                ).attributes.media.value = '(prefers-color-scheme: dark)';
                PNotify.notice({
                  title: 'Mode Change',
                  text: 'From now on, notices will show in system default mode.',
                });
              });

            document
              .getElementById('mode-light')
              .addEventListener('change', (e) => {
                PNotify.defaults.mode = 'light';
                document.getElementById(
                  'bootstrap-light'
                ).attributes.media.value =
                  '(prefers-color-scheme: no-preference), (prefers-color-scheme: light), (prefers-color-scheme: dark)';
                document.getElementById(
                  'bootstrap-dark'
                ).attributes.media.value = '(width: 0px)';
                PNotify.notice({
                  title: 'Mode Change',
                  text: 'From now on, notices will show in light mode.',
                });
              });

            document
              .getElementById('mode-dark')
              .addEventListener('change', (e) => {
                PNotify.defaults.mode = 'dark';
                document.getElementById(
                  'bootstrap-light'
                ).attributes.media.value = '(width: 0px)';
                document.getElementById(
                  'bootstrap-dark'
                ).attributes.media.value =
                  '(prefers-color-scheme: no-preference), (prefers-color-scheme: light), (prefers-color-scheme: dark)';
                PNotify.notice({
                  title: 'Mode Change',
                  text: 'From now on, notices will show in dark mode.',
                });
              });
          });
        </script>
      </div>
      <div class="card mt-3">
        <h5 class="card-header">PNotify Core</h5>
        <div class="card-body">
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Regular Notice',
                text: 'Check me out! I\'m a notice.'
              });
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.info({
                title: 'New Thing',
                text: 'Just to let you know, something happened.'
              });
            "
          >
            Info Message
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.success({
                title: 'Success!',
                text: 'That thing that you were trying to do worked.'
              });
            "
          >
            Success Message
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.error({
                title: 'Oh No!',
                text: 'Something terrible happened.'
              });
            "
          >
            Error Message
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Font Awesome Icon',
                text: 'I have an icon that uses the Font Awesome icon styles.',
                icon: 'far fa-envelope'
              });
            "
          >
            Custom Icon (Font Awesome)
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'No Icon Notice',
                text: 'I have no icon.',
                icon: false
              });
            "
          >
            No Icon
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'There\'s No Time to Explain',
                text: 'OMG READ ME FAST, I\'M ABOUT TO GO AWAY!',
                delay: 1000
              });
            "
          >
            Fast Notice
          </button>
          <hr />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Sticky Notice',
                text: 'Check me out! I\'m a sticky (pinned) notice. You\'ll have to close me yourself.',
                hide: false
              });
            "
          >
            Sticky Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.info({
                title: 'Sticky Info',
                text: 'Sticky info, you know, like a newspaper covered in honey.',
                hide: false
              });
            "
          >
            Sticky Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.success({
                title: 'Sticky Success',
                text: 'Sticky success... I\'m not even gonna make a joke.',
                hide: false
              });
            "
          >
            Sticky Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.error({
                title: 'Uh Oh!',
                text: 'Something really terrible happened. You really need to read this, so I won\'t close automatically.',
                hide: false
              });
            "
          >
            Sticky Error
          </button>
          <hr />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Stickyish Notice',
                text: 'Check me out! I\'m a Stickyish notice. I won\'t hide automatically, but I\'ll close with everyone else when you click the modal backdrop.',
                delay: Infinity
              });
            "
          >
            Stickyish Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.info({
                title: 'Stickyish Info',
                text: 'Check me out! I\'m a Stickyish info. I won\'t hide automatically, but I\'ll close with everyone else when you click the modal backdrop.',
                delay: Infinity
              });
            "
          >
            Stickyish Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.success({
                title: 'Stickyish Success',
                text: 'Check me out! I\'m a Stickyish success. I won\'t hide automatically, but I\'ll close with everyone else when you click the modal backdrop.',
                delay: Infinity
              });
            "
          >
            Stickyish Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.error({
                title: 'Stickyish Error',
                text: 'Check me out! I\'m a Stickyish error. I won\'t hide automatically, but I\'ll close with everyone else when you click the modal backdrop.',
                delay: Infinity
              });
            "
          >
            Stickyish Error
          </button>
          <hr />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Custom Button Icons Notice',
                text: 'Check me out! My sticker and close buttons have custom icons!',
                hide: false,
                icons: {
                  prefix: PNotify.defaults.icons,

                  closer: 'fas fa-bomb',
                  sticker: 'fas',
                  stuck: 'fa-hourglass',
                  unstuck: 'fa-anchor'
                }
              });
            "
          >
            Custom Button Icons
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'No Sticky Button Notice',
                text: 'Check me out! I\'m a sticky notice with no unsticky button. You\'ll have to close me manually.',
                hide: false,
                sticker: false
              });
            "
          >
            No Sticky Button
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'No Close Button Notice',
                text: 'But, how are you supposed to close me?',
                hide: false,
                closer: false
              });
            "
          >
            No Close Button
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Permanent Buttons Notice',
                text: 'My buttons are really lonely, so they\'re gonna hang out with us.',
                closerHover: false,
                stickerHover: false
              });
            "
          >
            Permanent Buttons
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              if (window.permanotice) {
                window.permanotice.open();
              } else {
                window.permanotice = PNotify.notice({
                  title: 'Now Look Here',
                  text: 'There\'s something you need to know, and I won\'t go away until you come to grips with it.',
                  hide: false,
                  closer: false,
                  sticker: false,
                  modules: new Map([
                    ...PNotify.defaultModules,
                    [PNotifyMobile, {
                      swipeDismiss: false
                    }]
                  ])
                });
              }
            "
          >
            Permanotice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              if (window.permanotice) {
                window.permanotice.close();
              }
            "
          >
            Close Permanotice
          </button>
          <hr />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Non-Blocking Notice',
                text: 'I\'m a special kind of notice called &quot;non-blocking&quot;. When you hover over me I\'ll fade to show the elements underneath. Feel free to click any of them just like I wasn\'t even here.\n\nNote: HTML links don\'t trigger in some very old browsers, due to security settings.',
                addModelessClass: 'nonblock'
              });
            "
          >
            Using NonBlock.js
          </button>
          <small>(Click through to things underneath the notice.)</small>
          <hr />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'See Through Notice',
                text: 'No one ever pays attention to me. Why should they? I\'m practically invisible.',
                addClass: 'translucent'
              });
              // You need this CSS:
              // [data-pnotify].pnotify.translucent.pnotify-fade-in {
              //   opacity: 0.8;
              // }
            "
          >
            Translucent
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'No Shadow Notice',
                text: 'I don\'t have a shadow. (It\'s cause I\'m a vampire or something. Or is that reflections...)',
                shadow: false
              });
            "
          >
            No Shadow Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({title: 'Check me out! I\'m a notice.'});
            "
          >
            Just Title
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice('Check me out! I\'m a notice.');
            "
          >
            Just Text
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice(Math.round(Math.random()*9999));
            "
          >
            Number
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'No Mouse Reset Notice',
                text: 'I don\'t care if you move your mouse over me, I\'ll disappear when I want.',
                mouseReset: false
              });
            "
          >
            No Mouse Reset
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Fast Fading Notice',
                text: 'I fade in and out really quickly.',
                animateSpeed: 'fast'
              });
            "
          >
            Fast Fading
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'No Effect Notice',
                text: 'I don\'t even bother to animate. I\'m too cool for that.',
                animation: 'none'
              });
            "
          >
            No Effect
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                text: document.getElementById('form_notice').innerHTML,
                textTrusted: true,
                icon: false,
                width: 'auto',
                maxTextHeight: null,
                hide: false,
                closer: false,
                sticker: false
              });
              notice.refs.elem.querySelector('form [name=cancel]').addEventListener('click', () => notice.close());
              notice.refs.elem.querySelector('form').addEventListener('submit', e => {
                e.preventDefault();
                const username = notice.refs.elem.querySelector('form input[name=username]').value;
                if (!username) {
                  alert('Please provide a username.');
                  return;
                }
                notice.update({
                  title: 'Welcome',
                  text: 'Successfully logged in as ' + username,
                  textTrusted: false,
                  icon: true,
                  width: PNotify.defaults.width,
                  hide: true,
                  type: 'success',
                  closer: true,
                  sticker: true
                });
              });
            "
          >
            Forms
          </button>
          <div id="form_notice" style="display: none">
            <form action="" method="post">
              <div class="mt-0 mb-3">
                <h3>Login to Continue</h3>
                <p>Just an example.</p>
                <hr />
              </div>
              <div class="form-group">
                <label for="exampleFormUsername">Username</label>
                <input
                  class="form-control"
                  id="exampleFormUsername"
                  type="text"
                  name="username"
                />
              </div>
              <div class="form-group">
                <label for="exampleFormPassword">Password</label>
                <input
                  class="form-control"
                  id="exampleFormPassword"
                  type="password"
                  name="password"
                />
              </div>
              <div class="form-check">
                <input
                  class="form-check-input"
                  id="exampleFormRemember"
                  type="checkbox"
                  name="remember"
                />
                <label class="form-check-label" for="exampleFormRemember"
                  >Remember Me</label
                >
                <small class="form-text text-muted">Lasts for 2 weeks.</small>
              </div>
              <div class="mt-3">
                <input
                  class="btn btn-primary"
                  type="submit"
                  name="submit"
                  value="Submit"
                />
                <input
                  class="btn btn-secondary ml-3"
                  type="button"
                  name="cancel"
                  value="Cancel"
                />
              </div>
            </form>
          </div>
          <button
            class="btn btn-light my-1 source"
            onclick="
              if (!window.domNotice) {
                window.domNotice = PNotify.notice({
                  title: document.getElementById('dom_notice_title'),
                  text: document.getElementById('dom_notice_text'),
                  icon: false,
                  maxTextHeight: null
                });
              } else {
                window.domNotice.open();
              }
            "
          >
            DOM Element
          </button>
          <div style="display: none">
            <h4 id="dom_notice_title">DOM Element Notice</h4>
            <div id="dom_notice_text" class="accordion">
              <div class="card">
                <div class="card-header" id="headingOne">
                  <h5 class="mb-0">
                    <button
                      class="btn btn-link"
                      type="button"
                      data-toggle="collapse"
                      data-target="#collapseOne"
                      aria-expanded="true"
                      aria-controls="collapseOne"
                    >
                      Check me out!
                    </button>
                  </h5>
                </div>
                <div
                  id="collapseOne"
                  class="collapse show"
                  aria-labelledby="headingOne"
                  data-parent="#dom_notice_text"
                >
                  <div class="card-body">
                    I'm a notice with a DOM element in it.
                  </div>
                </div>
              </div>
              <div class="card">
                <div class="card-header" id="headingTwo">
                  <h5 class="mb-0">
                    <button
                      class="btn btn-link collapsed"
                      type="button"
                      data-toggle="collapse"
                      data-target="#collapseTwo"
                      aria-expanded="false"
                      aria-controls="collapseTwo"
                    >
                      Isn't that cool!
                    </button>
                  </h5>
                </div>
                <div
                  id="collapseTwo"
                  class="collapse"
                  aria-labelledby="headingTwo"
                  data-parent="#dom_notice_text"
                >
                  <div class="card-body">Of course it is.</div>
                </div>
              </div>
              <div class="card">
                <div class="card-header" id="headingThree">
                  <h5 class="mb-0">
                    <button
                      class="btn btn-link collapsed"
                      type="button"
                      data-toggle="collapse"
                      data-target="#collapseThree"
                      aria-expanded="false"
                      aria-controls="collapseThree"
                    >
                      Hey, one thing though!
                    </button>
                  </h5>
                </div>
                <div
                  id="collapseThree"
                  class="collapse"
                  aria-labelledby="headingThree"
                  data-parent="#dom_notice_text"
                >
                  <div class="card-body">
                    The DOM element is inserted into the notice, so it will be
                    ripped out of the DOM if it is already somewhere else.
                  </div>
                </div>
              </div>
            </div>
          </div>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Click Notice',
                text: 'I wish someone would click me.'
              });
              notice.refs.elem.style.cursor = 'pointer';
              notice.on('click', e => {
                if ([...notice.refs.elem.querySelectorAll('.pnotify-closer *, .pnotify-sticker *')].indexOf(e.target) !== -1) {
                  return;
                }
                notice.update({
                  type: 'success',
                  text: 'Yay, you clicked me!&lt;div style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Happy_smiley_face.png/240px-Happy_smiley_face.png&quot; /&gt;&lt;/div&gt;',
                  textTrusted: true,
                  maxTextHeight: null
                });
              });
            "
          >
            Click on It
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Click Close Notice',
                text: 'Click me anywhere to dismiss me.',
                closer: false,
                sticker: false
              });
              notice.on('click', () => {
                notice.close();
              });
            "
          >
            Click to Close
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Big Notice',
                text: 'Check me out! I\'m tall and wide, even though my text isn\'t.',
                width: '500px',
                minHeight: '400px'
              });
            "
          >
            Huge
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Max Text Height Notice',
                text: 'Check me out! I\'ve got a ton of text, but a pretty small max text height. Since my text is too tall, I\'ve got scrollbars to help you. '+[...(new Array(100))].map((v, i) => i).join(', '),
                maxTextHeight: '180px'
              });
            "
          >
            Max Text Height
          </button>
          <script type="text/javascript">
            window.showRich = function showRich() {
              PNotify.notice({
                title:
                  '<span style="color: green;">Rich Content Notice</' + 'span>',
                titleTrusted: true,
                text:
                  '<span style="color: blue;">Look at my beautiful <strong>strong</' +
                  'strong>, <em>emphasized</' +
                  'em>, and <span style="font-size: 1.5em;">large</' +
                  'span> text.</' +
                  'span>',
                textTrusted: true,
                maxTextHeight: null,
              });
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showRich();
            "
          >
            Rich Text
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: '&lt;em&gt;Escaped Notice&lt;/em&gt;',
                text: document.getElementById('evil_html').innerHTML,
              });
            "
          >
            Or Keep it Safe
          </button>
          <div id="evil_html" style="display: none">
            <div>As you can see, I don't allow HTML in my content.</div>
            <div>This prevents things like cross site scripting attacks:</div>
            <script type="text/javascript">
              (() => {
                // Here would be the XSS attack.
              })();
            </script>
          </div>
          <script type="text/javascript">
            window.dynNotice = function dynNotice() {
              let percent = 0;
              const notice = PNotify.info({
                text: 'Please Wait',
                icon: 'fas fa-spinner fa-pulse',
                hide: false,
                shadow: false,
                width: '200px',
                closer: false,
                sticker: false,
              });

              notice.on('pnotify:afterOpen', () => {
                setTimeout(() => {
                  notice.update({ title: false });
                  const interval = setInterval(() => {
                    percent += 2;
                    const options = {
                      text: percent + '% complete.',
                    };
                    if (percent === 80) {
                      options.title = 'Almost There';
                    }
                    if (percent >= 100) {
                      window.clearInterval(interval);
                      options.title = 'Done!';
                      options.type = 'success';
                      options.hide = true;
                      options.icon = 'fas fa-check';
                      options.shadow = true;
                      options.width = PNotify.defaults.width;
                      options.closer = true;
                      options.sticker = true;
                    }
                    notice.update(options);
                  }, 120);
                }, 2000);
              });
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              dynNotice();
            "
          >
            Dynamic
          </button>
          <hr />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Custom Styling',
                text: 'I have a custom styling name that\'s used to give me special styling. I always wanted to be pretty. I also use NonBlock.js when modeless.',
                styling: 'custom',
                maxTextHeight: null,
                addModelessClass: 'nonblock',
                icon: 'far fa-file-image fa-3x'
              });
            "
          >
            Custom Styling
          </button>
          <br />
          <a
            href="javascript:void(0);"
            onclick="
              if (!window.growlModal) {
                window.growlModal = PNotify.info({
                  title: 'Styling Notices',
                  text: document.getElementById('growl'),
                  icon: 'fas fa-code',
                  hide: false,
                  destroy: false,
                  autoOpen: false,
                  width: '80vw',
                  maxTextHeight: null,
                  sticker: false,
                  stack: new PNotify.Stack({ modal: true, overlayClosesPinned: true })
                });
              }
              window.growlModal.open();
            "
            >How to custom style like this.</a
          >
          <div style="display: none">
            <div id="growl" style="max-height: 70vh; overflow-y: auto">
              <p>
                To custom style a notice, you can use a styling name like in the
                demo. For this example, I've used "<strong>custom</strong>".
              </p>
              <p>
                Classes with the styling as a prefix get added to various
                elements for styling. You want your selectors to be more
                specific than PNotify's selectors, so you can use
                "[data-pnotify]" to add specificity. This is how the built-in
                themes work.
              </p>
              <p>Here's the CSS that makes it look like those Growl notices:</p>
              <pre
                style="min-width: 100%"
              ><code class="css">[data-pnotify].<strong>custom</strong>-elem {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 10pt;
  line-height: 1.1;
}
[data-pnotify] .<strong>custom</strong>-container {
  background-color: #404040;
  background-image: none;
  border: none;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
  padding: 15px;
  font-size: 15px;
}
[data-pnotify] .<strong>custom</strong>-title,
[data-pnotify] .<strong>custom</strong>-text {
  margin-left: 50px;
  color: #FFF;
}
[data-pnotify] .<strong>custom</strong>-title {
  font-weight: bold;
  font-size: 15px;
}
[data-pnotify] .<strong>custom</strong>-icon {
  color: #FFA;
}</code></pre>
            </div>
          </div>
        </div>

        <h5 class="card-header">
          Stacks
          <small
            >Position, order, and group notices. See the
            <a href="#stacks">main stacks section</a> for even more
            demos.</small
          >
        </h5>
        <div class="card-body">
          <button
            class="btn btn-light my-1 source"
            onclick="
              // In order to keep all notices around once they close, set the
              // default destroy option to false.
              //
              // PNotify.defaults.destroy = false;
              PNotify.defaultStack.openLast();
            "
          >
            Open Last Notice (Default Stack)
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              // In order to keep all notices around once they close, set the
              // default destroy option to false.
              //
              // PNotify.defaults.destroy = false;
              PNotify.defaultStack.open();
            "
          >
            Open All Notices (Default Stack)
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              if (typeof window.maxOpenWait === 'undefined') {
                window.maxOpenWait = new PNotify.Stack({dir1: 'down', dir2: 'right', firstpos1: 25, firstpos2: 25, modal: false, maxOpen: 2, maxStrategy: 'wait', maxClosureCausesWait: false});
              }
              PNotify.notice({
                title: 'Stack Limit Notice',
                text: 'I get anxious around other notices, so I\'ll keep only one friend around.',
                stack: window.maxOpenWait
              });
            "
          >
            Limit a Stack by Holding Notices
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              if (typeof window.maxOpenClose === 'undefined') {
                window.maxOpenClose = new PNotify.Stack({dir1: 'up', dir2: 'right', firstpos1: 25, firstpos2: 25, modal: false, maxOpen: 2, maxStrategy: 'close', maxClosureCausesWait: false});
              }
              PNotify.notice({
                title: 'Stack Limit Notice',
                text: 'I get anxious around other notices, so I\'ll keep only one friend around.',
                stack: window.maxOpenClose
              });
            "
          >
            Limit a Stack by Closing Notices
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.defaultStack.close(true);
              PNotify.defaultStack.maxOpen = Infinity;
              PNotify.defaultStack.modal = false;
            "
          >
            Default Stack to Modeless
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.defaultStack.close(true);
              PNotify.defaultStack.maxOpen = 1;
              PNotify.defaultStack.modal = 'ish';
            "
          >
            Default Stack Back to Modalish
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.defaultStack.close();
            "
          >
            Close All Notices (Default Stack)
          </button>
          <br />
          <small
            >Opening previous notices requires
            <code>PNotify.defaults.destroy = false;</code></small
          >
        </div>

        <h5 class="card-header">
          Lifecycle Events
          <small>Manipulate the notice during its lifecycle.</small>
        </h5>
        <div class="card-body">
          <button
            class="btn btn-light my-1 source"
            onclick="
              const dontAlert = () => {};
              const initListener = event => {
                console.log(event.type, event.detail);
                alert('I\'m listening for when the notice initializes. This and \'mount\' are the only PNotify lifecycle events that bubble. The event object has a reference to the notice.');
              };
              const mountListener = event => {
                console.log(event.type, event.detail);
                dontAlert('I\'m listening for when the notice has mounted into the DOM.');
              };
              document.body.addEventListener('pnotify:init', initListener);
              document.body.addEventListener('pnotify:mount', mountListener);
              const notice = PNotify.notice({
                title: 'I\'m Here',
                text: 'I have a listener for each of my lifecycle events. I\'ll fire events for all my listeners while I change states.',
                autoOpen: false,
              });
              document.body.removeEventListener('pnotify:init', initListener);
              document.body.removeEventListener('pnotify:mount', mountListener);
              notice.on('pnotify:update', event => {
                console.log(event.type, event.detail);
                dontAlert('I\'m listening for when the notice changes state.');
              });
              notice.on('pnotify:beforeOpen', event => {
                console.log(event.type, event.detail);
                // Use event.preventDefault() to cancel opening.
                alert('I\'m listening for before the notice opens.\n\nThere are more events you can listen for, but this is the last alert you\'ll see. Check the code to see them all.');
              });
              notice.on('pnotify:afterOpen', event => {
                console.log(event.type, event.detail);
                dontAlert('I\'m listening for after the notice opens.');
              });
              notice.on('pnotify:enterModal', event => {
                console.log(event.type, event.detail);
                dontAlert('I\'m listening for when the notice enters a modal state.');
              });
              notice.on('pnotify:leaveModal', event => {
                console.log(event.type, event.detail);
                dontAlert('I\'m listening for when the notice leaves a modal state.');
              });
              notice.on('pnotify:beforeClose', event => {
                console.log(event.type, event.detail);
                // Use event.preventDefault() to cancel close. Use notice.queueClose() to set the close timer again.
                dontAlert('I\'m listening for before the notice closes.');
              });
              notice.on('pnotify:afterClose', event => {
                console.log(event.type, event.detail);
                dontAlert('I\'m listening for after the notice closes.');
              });
              notice.on('pnotify:beforeDestroy', event => {
                console.log(event.type, event.detail);
                // Use event.preventDefault() to cancel destroy.
                dontAlert('I\'m listening for before the notice is destroyed.');
              });
              notice.on('pnotify:afterDestroy', event => {
                console.log(event.type, event.detail);
                dontAlert('I\'m listening for after the notice is destroyed.');
              });
              notice.open();
            "
          >
            Notice with Event Listeners
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Notice',
                text: 'Right now I\'m a notice.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}]
                ])
              });

              let off = notice.on('pnotify:beforeClose', event => {
                listener1(event);
              });

              const listener1 = event => {
                if (!event.detail.timerHide) {
                  off();
                  return;
                }
                notice.update({
                  title: 'Error',
                  text: 'Uh oh. Now I\'ve become an error.',
                  type: 'error'
                });
                notice.attention('swing');
                notice.queueClose();
                event.preventDefault();
                off();
                off = notice.on('pnotify:beforeClose', event => {
                  listener2(event);
                });
              };

              const listener2 = event => {
                if (!event.detail.timerHide) {
                  off();
                  return;
                }
                notice.update({
                  title: 'Success',
                  text: 'I fixed the error!',
                  type: 'success'
                });
                notice.attention('swing');
                notice.queueClose();
                event.preventDefault();
                off();
                off = notice.on('pnotify:beforeClose', event => {
                  listener3(event);
                });
              };

              const listener3 = event => {
                if (!event.detail.timerHide) {
                  off();
                  return;
                }
                notice.update({
                  title: 'Info',
                  text: 'Everything\'s cool now.',
                  type: 'info'
                });
                notice.attention('swing');
                notice.queueClose();
                event.preventDefault();
                off();
              };
            "
          >
            Notice to Error to Success to Info
          </button>
          <script type="text/javascript">
            window.fakeLoad = function fakeLoad() {
              let curValue = 1;
              let progress;

              // Make a loader.
              const notice = PNotify.notice({
                title: 'Creating series of tubes',
                text:
                  '<div class="progress">\n' +
                  '  <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></' +
                  'div>\n' +
                  '</' +
                  'div>',
                textTrusted: true,
                icon: 'fas fa-cog fa-spin',
                hide: false,
                destroy: true,
                closer: false,
                sticker: false,
              });

              notice.on('pnotify:afterOpen', () => {
                progress = notice.refs.elem.querySelector('.progress-bar');
                progress.style.width = curValue + '%';
                progress.attributes['aria-valuenow'].value = curValue;
                // Pretend to do something.
                let plus = 1;
                const timer = setInterval(() => {
                  if (curValue === 70) {
                    plus = 0.25;
                    notice.update({
                      title: 'Aligning discrete worms',
                      icon: 'fas fa-circle-notch fa-spin',
                    });
                  }
                  if (curValue === 80) {
                    notice.update({
                      title: 'Connecting end points',
                      icon: 'fas fa-sync fa-spin',
                    });
                  }
                  if (curValue === 90) {
                    notice.update({
                      title: 'Dividing and conquering',
                      icon: 'fas fa-spinner fa-pulse',
                    });
                  }
                  if (curValue >= 100) {
                    // Clean up the interval.
                    window.clearInterval(timer);
                    notice.close();
                    return;
                  }
                  curValue += plus;
                  progress.style.width = curValue + '%';
                  progress.attributes['aria-valuenow'].value = curValue;
                }, 65);
              });
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              fakeLoad();
            "
          >
            Progress Loader
          </button>
        </div>
      </div>
    </div>

    <div id="web-notifications"></div>
    <div id="demos-modules" class="container page-section">
      <div class="my-3">
        <h2>Module Demos</h2>
        <hr />
      </div>
      <div class="card">
        <h5 class="card-header">
          Desktop Module
          <small
            >Notifications that display even when the web page is not
            visible.</small
          >
        </h5>
        <div class="card-body">
          <div class="float-right">
            Implements the
            <a href="http://www.w3.org/TR/notifications/" target="_blank"
              >Web Notifications spec</a
            >.
          </div>
        </div>
        <div class="card-body">
          <p>
            The first time you click one of these buttons, you will be asked to
            grant permission for this site to show notices. Then you can click
            them again to see the desktop notification.
          </p>
          <p>
            If your browser doesn't support Web Notifications, or you deny
            permission to show them, you will only see regular in-browser
            notices. You can check
            <a href="http://caniuse.com/notifications" target="_blank">here</a>.
          </p>
          <hr />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Desktop Notice',
                text: 'I\'ll appear as a desktop notification. Unless I can\'t. I\'ll still appear as a regular PNotify notice then.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {}]
                ])
              });
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.info({
                title: 'Desktop Info',
                text: 'Hey there. Something happened.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {}]
                ])
              });
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.success({
                title: 'Desktop Success',
                text: 'All done! Come back to my tab!',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {}]
                ])
              });
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.error({
                title: 'Desktop Error',
                text: 'Serious error is serious.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {}]
                ])
              });
            "
          >
            Error
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Desktop Custom Icon',
                text: 'I\'ve got a custom icon.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {
                    icon: 'includes/le_happy_face_by_luchocas-32.png'
                  }]
                ])
              });
            "
          >
            Custom Icon
          </button>
          <!-- <button class="btn btn-light my-1 source" onclick="
          PNotify.notice({
            title: 'Desktop Image',
            type: 'info',
            text: 'I\'ve got an image.&lt;div style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Happy_smiley_face.png/240px-Happy_smiley_face.png&quot; /&gt;&lt;/div&gt;',
            textTrusted: true,
            modules: new Map([
              ...PNotify.defaultModules,
              [PNotifyDesktop, {
                text: 'I\'ve got an image.',
                icon: false,
                options: {
                  image: 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Happy_smiley_face.png/240px-Happy_smiley_face.png'
                }
              }]
            ])
          });
        ">Image</button> -->
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Alternate Text Notice - Browser',
                text: 'This text appears on the &lt;strong&gt;browser&lt;/strong&gt;.',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {
                    title: 'Alternate Text Notice - Desktop',
                    text: 'This text appears on the *desktop*.'
                  }]
                ])
              });
            "
          >
            Alternate Text and Title
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Clicky Desktop Notice',
                text: 'Click me.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {
                    icon: false
                  }]
                ])
              });
              notice.on('click', e => {
                if ([...notice.refs.elem.querySelectorAll('.pnotify-closer *, .pnotify-sticker *')].indexOf(e.target) !== -1) {
                  return;
                }
                alert('Hey! You clicked the desktop notification!');
              });
            "
          >
            Clicky
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Sticky Desktop Notice',
                text: 'I\'m a sticky notice. (Some browsers don\'t allow sticky Web Notifications.)',
                hide: false,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {
                    icon: false
                  }]
                ])
              });
              notice.on('click', e => {
                if ([...notice.refs.elem.querySelectorAll('.pnotify-closer *, .pnotify-sticker *')].indexOf(e.target) !== -1) {
                  return;
                }
                alert('Hey! You clicked the desktop notification!');
              });
            "
          >
            Sticky Clicky
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Dynamic Desktop Notice',
                text: 'I\'m a dynamic desktop notice.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {}]
                ])
              });
              setTimeout(() => {
                notice.update({
                  type: 'info',
                  text: 'Now I\'m an info box!'
                });
              }, 1000);
            "
          >
            Dynamic
          </button>
          <button
            class="btn btn-light my-1 source"
            title="Disabling fallback makes the notice not appear at all if it can't appear as a desktop notice."
            onclick="
              PNotify.notice({
                title: 'Desktop Notice',
                text: 'I won\'t fall back to a regular notice.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyDesktop, {
                    fallback: false
                  }]
                ])
              });
            "
          >
            No Fallback
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotifyDesktop.permission();
            "
          >
            Explicitly Ask for Notice Permission
          </button>
        </div>

        <h5 class="card-header">
          Mobile Module <small>Notices on mobile phones and tablets.</small>
        </h5>
        <div class="card-body">
          <div class="alert alert-info">
            The Mobile module is added to PNotify.defaultModules on this page,
            so most of the demos on this page work on mobile.
          </div>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'No Swipe Dismiss Notice',
                text: 'If you\'re on a mobile device, I won\'t respond to your swipes.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyMobile, {
                    swipeDismiss: false
                  }]
                ])
              });
            "
          >
            No Swipe Dismiss
          </button>
        </div>

        <h5 class="card-header">
          Countdown Module
          <small>Give an indication of how much time is left.</small>
        </h5>
        <div class="card-body">
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Countdown Notice',
                text: 'I\'ve got a countdown display!',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyCountdown, {}]
                ])
              });
            "
          >
            Countdown Notice
          </button>
          <div class="my-3">
            Try out the options:
            <div class="my-1">
              Type
              <select
                id="countdown_type"
                class="form-control"
                style="display: inline; width: auto"
              >
                <option value="notice">notice</option>
                <option value="info">info</option>
                <option value="success">success</option>
                <option value="error">error</option>
              </select>
            </div>
            <div class="my-1">
              Anchor
              <select
                id="countdown_anchor"
                class="form-control"
                style="display: inline; width: auto"
              >
                <option value="top">top</option>
                <option value="bottom" selected>bottom</option>
                <option value="left">left</option>
                <option value="right">right</option>
              </select>
            </div>
            <div class="my-1">
              <label>
                <input type="checkbox" id="countdown_reverse" />
                Reverse
              </label>
            </div>
            <button
              class="btn btn-light my-1 source"
              onclick="
                const type = document.getElementById('countdown_type').value;
                const anchor = document.getElementById('countdown_anchor').value;
                const reverse = document.getElementById('countdown_reverse').checked;
                PNotify.alert({
                  type: type,
                  title: 'Countdown Notice',
                  text: 'I\'ve got a countdown display.',
                  modules: new Map([
                    ...PNotify.defaultModules,
                    [PNotifyCountdown, {
                      anchor: anchor,
                      reverse: reverse
                    }]
                  ])
                });
              "
            >
              Notify!
            </button>
          </div>
        </div>

        <h5 class="card-header">
          Animate Module
          <small
            >Fluid CSS animations using
            <a href="https://daneden.github.io/animate.css/" target="_blank"
              >Animate.css</a
            >.</small
          >
        </h5>
        <div class="card-body">
          Some good looking examples:<br />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Animate.css Effect',
                text: 'I use effects from Animate.css. Such smooth CSS3 transitions make me feel like butter.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {
                    inClass: 'rotateInUpRight',
                    outClass: 'rotateOutUpRight'
                  }]
                ])
              });
            "
          >
            Sidenote
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Animate.css Effect',
                text: 'I use effects from Animate.css. Such smooth CSS3 transitions make me feel like butter.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {
                    inClass: 'zoomInLeft',
                    outClass: 'zoomOutRight'
                  }]
                ])
              });
            "
          >
            Zoom, Zoom
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Animate.css Effect',
                text: 'I use effects from Animate.css. Such smooth CSS3 transitions make me feel like butter.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {
                    inClass: 'rotateInDownLeft',
                    outClass: 'rotateOutUpRight'
                  }]
                ])
              });
            "
          >
            Shuffling Cards
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Animate.css Effect',
                text: 'I use effects from Animate.css. Such smooth CSS3 transitions make me feel like butter.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {
                    inClass: 'bounceInLeft',
                    outClass: 'bounceOutRight'
                  }]
                ])
              });
            "
          >
            Zippy
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Animate.css Effect',
                text: 'I use effects from Animate.css. Such smooth CSS3 transitions make me feel like butter.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {
                    inClass: 'bounceInDown',
                    outClass: 'hinge'
                  }]
                ])
              });
            "
          >
            Off the Handle
          </button>
          <div class="my-3">
            Or build your own:
            <div class="my-1">
              Effect in
              <select
                id="animate_in"
                class="form-control"
                style="display: inline; width: auto"
              >
                <option value="bounceIn">bounceIn</option>
                <option value="bounceInDown">bounceInDown</option>
                <option value="bounceInLeft">bounceInLeft</option>
                <option value="bounceInRight">bounceInRight</option>
                <option value="bounceInUp">bounceInUp</option>
                <option value="fadeIn">fadeIn</option>
                <option value="fadeInDown">fadeInDown</option>
                <option value="fadeInDownBig">fadeInDownBig</option>
                <option value="fadeInLeft">fadeInLeft</option>
                <option value="fadeInLeftBig">fadeInLeftBig</option>
                <option value="fadeInRight">fadeInRight</option>
                <option value="fadeInRightBig">fadeInRightBig</option>
                <option value="fadeInUp">fadeInUp</option>
                <option value="fadeInUpBig">fadeInUpBig</option>
                <option value="flipInX">flipInX</option>
                <option value="flipInY">flipInY</option>
                <option value="lightSpeedIn">lightSpeedIn</option>
                <option value="rotateIn">rotateIn</option>
                <option value="rotateInDownLeft">rotateInDownLeft</option>
                <option value="rotateInDownRight">rotateInDownRight</option>
                <option value="rotateInUpLeft">rotateInUpLeft</option>
                <option value="rotateInUpRight">rotateInUpRight</option>
                <option value="rollIn">rollIn</option>
                <option value="zoomIn">zoomIn</option>
                <option value="zoomInDown">zoomInDown</option>
                <option value="zoomInLeft">zoomInLeft</option>
                <option value="zoomInRight">zoomInRight</option>
                <option value="zoomInUp">zoomInUp</option>
                <option value="slideInDown">slideInDown</option>
                <option value="slideInLeft">slideInLeft</option>
                <option value="slideInRight">slideInRight</option>
                <option value="slideInUp">slideInUp</option>
              </select>
            </div>
            <div class="my-1">
              Effect out
              <select
                id="animate_out"
                class="form-control"
                style="display: inline; width: auto"
              >
                <option value="bounceOut">bounceOut</option>
                <option value="bounceOutDown">bounceOutDown</option>
                <option value="bounceOutLeft">bounceOutLeft</option>
                <option value="bounceOutRight">bounceOutRight</option>
                <option value="bounceOutUp">bounceOutUp</option>
                <option value="fadeOut">fadeOut</option>
                <option value="fadeOutDown">fadeOutDown</option>
                <option value="fadeOutDownBig">fadeOutDownBig</option>
                <option value="fadeOutLeft">fadeOutLeft</option>
                <option value="fadeOutLeftBig">fadeOutLeftBig</option>
                <option value="fadeOutRight">fadeOutRight</option>
                <option value="fadeOutRightBig">fadeOutRightBig</option>
                <option value="fadeOutUp">fadeOutUp</option>
                <option value="fadeOutUpBig">fadeOutUpBig</option>
                <option value="flipOutX">flipOutX</option>
                <option value="flipOutY">flipOutY</option>
                <option value="lightSpeedOut">lightSpeedOut</option>
                <option value="rotateOut">rotateOut</option>
                <option value="rotateOutDownLeft">rotateOutDownLeft</option>
                <option value="rotateOutDownRight">rotateOutDownRight</option>
                <option value="rotateOutUpLeft">rotateOutUpLeft</option>
                <option value="rotateOutUpRight">rotateOutUpRight</option>
                <option value="hinge">hinge</option>
                <option value="rollOut">rollOut</option>
                <option value="zoomOut">zoomOut</option>
                <option value="zoomOutDown">zoomOutDown</option>
                <option value="zoomOutLeft">zoomOutLeft</option>
                <option value="zoomOutRight">zoomOutRight</option>
                <option value="zoomOutUp">zoomOutUp</option>
                <option value="slideOutDown">slideOutDown</option>
                <option value="slideOutLeft">slideOutLeft</option>
                <option value="slideOutRight">slideOutRight</option>
                <option value="slideOutUp">slideOutUp</option>
              </select>
            </div>
            <button
              class="btn btn-light my-1 source"
              onclick="
                const animateIn = document.getElementById('animate_in').value;
                const animateOut = document.getElementById('animate_out').value;
                PNotify.notice({
                  title: 'Animate.css Effect',
                  text: 'I use effects from Animate.css. Such smooth CSS3 transitions make me feel like butter.',
                  modules: new Map([
                    ...PNotify.defaultModules,
                    [PNotifyAnimate, {
                      inClass: animateIn,
                      outClass: animateOut
                    }]
                  ])
                });
              "
            >
              Notify!
            </button>
          </div>
          Attention seekers:<br />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Attention Seeker',
                text: 'Click the button to see how you can highlight the notice with the Animate module:',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}],
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Bounce!',
                      primary: true,
                      click: notice => notice.attention('bounce')
                    }]
                  }]
                ])
              });
            "
          >
            Bounce
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Attention Seeker',
                text: 'Click the button to see how you can highlight the notice with the Animate module:',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}],
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Flash!',
                      primary: true,
                      click: notice => notice.attention('flash')
                    }]
                  }]
                ])
              });
            "
          >
            Flash
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Attention Seeker',
                text: 'Click the button to see how you can highlight the notice with the Animate module:',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}],
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Pulse!',
                      primary: true,
                      click: notice => notice.attention('pulse')
                    }]
                  }]
                ])
              });
            "
          >
            Pulse
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Attention Seeker',
                text: 'Click the button to see how you can highlight the notice with the Animate module:',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}],
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Rubber Band!',
                      primary: true,
                      click: notice => notice.attention('rubberBand')
                    }]
                  }]
                ])
              });
            "
          >
            Rubber Band
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Attention Seeker',
                text: 'Click the button to see how you can highlight the notice with the Animate module:',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}],
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Shake!',
                      primary: true,
                      click: notice => notice.attention('shake')
                    }]
                  }]
                ])
              });
            "
          >
            Shake
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Attention Seeker',
                text: 'Click the button to see how you can highlight the notice with the Animate module:',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}],
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Swing!',
                      primary: true,
                      click: notice => notice.attention('swing')
                    }]
                  }]
                ])
              });
            "
          >
            Swing
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Attention Seeker',
                text: 'Click the button to see how you can highlight the notice with the Animate module:',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}],
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Tada!',
                      primary: true,
                      click: notice => notice.attention('tada')
                    }]
                  }]
                ])
              });
            "
          >
            Tada
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Attention Seeker',
                text: 'Click the button to see how you can highlight the notice with the Animate module:',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}],
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Wobble!',
                      primary: true,
                      click: notice => notice.attention('wobble')
                    }]
                  }]
                ])
              });
            "
          >
            Wobble
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Attention Seeker',
                text: 'Click the button to see how you can highlight the notice with the Animate module:',
                textTrusted: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyAnimate, {}],
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Jello!',
                      primary: true,
                      click: notice => notice.attention('jello')
                    }]
                  }]
                ])
              });
            "
          >
            Jello
          </button>
        </div>

        <div id="confirm-module"></div>
        <h5 class="card-header">
          Confirm Module <small>Confirmation dialogs and prompts.</small>
        </h5>
        <div class="card-body">
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Confirmation Needed',
                text: 'Are you sure?',
                icon: 'fas fa-question-circle',
                hide: false,
                destroy: true,
                closer: false,
                sticker: false,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyConfirm, {
                    confirm: true
                  }]
                ])
              });
              notice.on('pnotify:confirm', () => alert('Ok, cool.'));
              notice.on('pnotify:cancel', () => alert('Oh ok. Chicken, I see.'));
            "
          >
            Confirm Dialog
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Confirmation Needed',
                text: 'Are you sure?',
                icon: 'fas fa-question-circle',
                hide: false,
                closer: false,
                sticker: false,
                destroy: true,
                stack: new PNotify.Stack({
                  dir1: 'down',
                  modal: true,
                  firstpos1: 25,
                  overlayClose: false
                }),
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyConfirm, {
                    confirm: true
                  }]
                ])
              });
              notice.on('pnotify:confirm', () => alert('Ok, cool.'));
              notice.on('pnotify:cancel', () => alert('Oh ok. Chicken, I see.'));
            "
          >
            Modal Confirm Dialog
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'Choose a Side',
                text: 'You have three options to choose from.',
                icon: 'fas fa-question-circle',
                hide: false,
                closer: false,
                sticker: false,
                destroy: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [
                      {
                        text: 'Fries',
                        primary: true,
                        click: notice => notice.update({
                          title: 'You\'ve Chosen a Side',
                          text: 'You want fries.',
                          icon: true,
                          closer: true,
                          sticker: true,
                          type: 'info',
                          hide: true,
                          modules: new Map(PNotify.defaultModules)
                        })
                      },
                      {
                        text: 'Mash',
                        click: notice => notice.update({
                          title: 'You\'ve Chosen a Side',
                          text: 'You want mashed potatoes.',
                          icon: true,
                          closer: true,
                          sticker: true,
                          type: 'info',
                          hide: true,
                          modules: new Map(PNotify.defaultModules)
                        })
                      },
                      {
                        text: 'Fruit',
                        click: notice => notice.update({
                          title: 'You\'ve Chosen a Side',
                          text: 'You want fruit.',
                          icon: true,
                          closer: true,
                          sticker: true,
                          type: 'info',
                          hide: true,
                          modules: new Map(PNotify.defaultModules)
                        })
                      }
                    ]
                  }]
                ])
              });
            "
          >
            Custom Buttons
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Input Needed',
                text: 'What side would you like?',
                icon: 'fas fa-question-circle',
                hide: false,
                closer: false,
                sticker: false,
                destroy: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyConfirm, {
                    prompt: true
                  }]
                ])
              });
              notice.on('pnotify:confirm', e => {
                notice.cancelClose();
                notice.update({
                  title: 'You\'ve Chosen a Side',
                  text: 'You want ' + e.detail.value + '.',
                  icon: true,
                  closer: true,
                  sticker: true,
                  type: 'info',
                  hide: true,
                  modules: new Map(PNotify.defaultModules)
                });
              });
              notice.on('pnotify:cancel', () => {
                notice.cancelClose();
                notice.update({
                  title: 'You Don\'t Want a Side',
                  text: 'No soup for you!',
                  icon: true,
                  closer: true,
                  sticker: true,
                  type: 'info',
                  hide: true,
                  modules: new Map(PNotify.defaultModules)
                });
              });
            "
          >
            Prompt Dialog
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              const notice = PNotify.notice({
                title: 'Input Needed',
                text: 'Write me a poem, please.',
                icon: 'fas fa-question-circle',
                hide: false,
                closer: false,
                sticker: false,
                destroy: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyConfirm, {
                    prompt: true,
                    promptMultiLine: true,
                    promptValue: 'Roses are red,\nViolets are blue,\n'
                  }]
                ])
              });
              notice.on('pnotify:confirm', e => {
                notice.cancelClose();
                notice.update({
                  title: 'Your Poem',
                  text: e.detail.value,
                  icon: true,
                  type: 'info',
                  hide: true,
                  closer: true,
                  sticker: true,
                  modules: new Map(PNotify.defaultModules)
                });
              });
              notice.on('pnotify:cancel', () => {
                notice.cancelClose();
                notice.update({
                  title: 'You Don\'t Like Poetry',
                  text: 'Roses are dead,\nViolets are dead,\nI suck at gardening.',
                  icon: true,
                  type: 'info',
                  hide: true,
                  closer: true,
                  sticker: true,
                  modules: new Map(PNotify.defaultModules)
                });
              });
            "
          >
            Multi Line Prompt Dialog
          </button>
          <hr />
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.notice({
                title: 'You Will Receive a Side',
                text: 'You have no choice.',
                icon: 'fas fa-info-circle',
                hide: false,
                closer: false,
                sticker: false,
                destroy: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Ok',
                      primary: true,
                      click: notice => notice.close()
                    }]
                  }]
                ])
              });
            "
          >
            Alert Style Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.info({
                title: 'You Will Receive a Side',
                text: 'You have no choice.',
                icon: 'fas fa-info-circle',
                hide: false,
                closer: false,
                sticker: false,
                destroy: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Ok',
                      primary: true,
                      click: notice => notice.close()
                    }]
                  }]
                ])
              });
            "
          >
            Alert Style Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.success({
                title: 'You Will Receive a Side',
                text: 'You have no choice.',
                icon: 'fas fa-info-circle',
                hide: false,
                closer: false,
                sticker: false,
                destroy: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Ok',
                      primary: true,
                      click: notice => notice.close()
                    }]
                  }]
                ])
              });
            "
          >
            Alert Style Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.error({
                title: 'You Will Receive a Side',
                text: 'You have no choice.',
                icon: 'fas fa-info-circle',
                hide: false,
                closer: false,
                sticker: false,
                destroy: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyConfirm, {
                    confirm: true,
                    buttons: [{
                      text: 'Ok',
                      primary: true,
                      click: notice => notice.close()
                    }]
                  }]
                ])
              });
            "
          >
            Alert Style Error
          </button>
        </div>

        <h5 class="card-header">
          Paginate Module
          <small>Show buttons to let the user page through notices.</small>
        </h5>
        <div class="card-body">
          <script type="text/javascript">
            window.showPaginate = function showPaginate(type) {
              if (typeof window.stackPaginate === 'undefined') {
                window.stackPaginate = new PNotify.Stack({
                  dir1: 'down',
                  dir2: 'left',
                  firstpos1: 25,
                  firstpos2: 25,
                  modal: false,
                  context: document.getElementById('paginate-context'),
                });
              }
              const opts = {
                title: "It's a Notice",
                text: 'The notice gives you a bit more context about the other notices.',
                stack: window.stackPaginate,
                destroy: true,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyPaginate, {}],
                ]),
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showPaginate('notice');
            "
          >
            Paginate Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showPaginate('info');
            "
          >
            Paginate Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showPaginate('success');
            "
          >
            Paginate Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showPaginate('error');
            "
          >
            Paginate Error
          </button>

          <div class="row justify-content-md-center mt-3">
            <div class="col-md-10">
              <div class="card">
                <div
                  id="paginate-context"
                  class="card-body"
                  style="height: 350px; position: relative; overflow: auto"
                >
                  <div class="my-3">
                    <h3>Paginate Demo</h3>
                    <hr />
                  </div>
                  <p>
                    I'm the context for the paginate demo. I'm here since the
                    Paginate module works best with a certain kind of setup:
                  </p>
                  <ul>
                    <li>Max 1 shown notice in the stack.</li>
                    <li>Destroy turned on. (So the count is correct.)</li>
                    <li>
                      Modalish turned off. (Or you can turn off the paginate
                      buttons for just the count.)
                    </li>
                  </ul>
                </div>
              </div>
            </div>
          </div>
        </div>

        <h5 class="card-header">
          Reference Module
          <small>A reference for when you are coding your own module.</small>
        </h5>
        <div class="card-body">
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.info({
                title: 'Reference Module',
                text: 'The reference module is a basic module that demonstrates how to write a PNotify module by implementing many of its features. You can find it in PNotifyReferenceComponent.html.',
                modules: new Map([
                  ...PNotify.defaultModules,
                  [PNotifyReference, {
                    labels: {
                      text: 'BARREL ROLL!'
                    }
                  }]
                ])
              });
            "
          >
            Reference Module Notice
          </button>
        </div>
      </div>
    </div>

    <div id="stacks" class="container page-section">
      <div class="my-3">
        <h2>Stacks <small>Position, order, and group notices.</small></h2>
        <hr />
      </div>
      <div class="card">
        <h5 class="card-header">Examples of Custom Stacks</h5>
        <div class="card-body">
          <button
            class="btn btn-light my-1 source"
            onclick="
              PNotify.info({
                title: 'PNotify Stacks',
                text: 'Stacks are used to position notices and determine where new notices will go when they\'re created. Each notice that\'s placed into a stack will be positioned related to the other notices in that stack.\n\nModeless stacks don\'t block the page. Modal stacks block the page so the user can only interact with the notices. Modalish stacks show only one notice, until the user interacts, then they can block the page and show all the notices.',
                icon: 'fas fa-bars',
                hide: false,
                sticker: false,
                destroy: true,
                stack: new PNotify.Stack({ modal: true, overlayClosesPinned: true })
              });
            "
          >
            What are stacks?
          </button>
          <hr />
          Modalish. Top Left. Moves down, then right. Pushes to stack top.<br />
          <script type="text/javascript">
            window.showStackTopLeft = function showStackTopLeft(type) {
              if (typeof window.stackTopLeft === 'undefined') {
                window.stackTopLeft = new PNotify.Stack({
                  dir1: 'down',
                  dir2: 'right',
                  firstpos1: 25,
                  firstpos2: 25,
                  push: 'top',
                  maxStrategy: 'close',
                });
              }
              const opts = {
                title: 'Over Here',
                text: "Check me out. I'm in a different stack.",
                stack: window.stackTopLeft,
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackTopLeft('notice');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackTopLeft('info');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackTopLeft('success');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackTopLeft('error');
            "
          >
            Error
          </button>
          <hr />
          Modalish. Bottom Left. Moves right, then up. Pushes to stack top.<br />
          <script type="text/javascript">
            window.showStackBottomLeft = function showStackBottomLeft(type) {
              if (typeof window.stackBottomLeft === 'undefined') {
                window.stackBottomLeft = new PNotify.Stack({
                  dir1: 'right',
                  dir2: 'up',
                  firstpos1: 25,
                  firstpos2: 25,
                  push: 'top',
                  maxStrategy: 'close',
                });
              }
              const opts = {
                title: 'Over Here',
                text: "Check me out. I'm in a different stack.",
                stack: window.stackBottomLeft,
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBottomLeft('notice');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBottomLeft('info');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBottomLeft('success');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBottomLeft('error');
            "
          >
            Error
          </button>
          <hr />
          Modalish. Bottom Right. Moves up, then left. Pushes to stack
          bottom.<br />
          <script type="text/javascript">
            window.showStackBottomRight = function showStackBottomRight(type) {
              if (typeof window.stackBottomRight === 'undefined') {
                window.stackBottomRight = new PNotify.Stack({
                  dir1: 'up',
                  dir2: 'left',
                  firstpos1: 25,
                  firstpos2: 25,
                });
              }
              const opts = {
                title: 'Over Here',
                text: "Check me out. I'm in a different stack.",
                stack: window.stackBottomRight,
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBottomRight('notice');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBottomRight('info');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBottomRight('success');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBottomRight('error');
            "
          >
            Error
          </button>
          <hr />
          Modeless. Top Center. Moves down. Pushes to stack bottom.<br />
          <script type="text/javascript">
            window.showStackTopCenter = function showStackTopCenter(type) {
              if (typeof window.stackTopCenter === 'undefined') {
                window.stackTopCenter = new PNotify.Stack({
                  dir1: 'down',
                  firstpos1: 25,
                  modal: false,
                  maxOpen: Infinity,
                });
              }
              const opts = {
                title: 'Over Here',
                text: "Check me out. I'm in a different stack.",
                stack: window.stackTopCenter,
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackTopCenter('notice');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackTopCenter('info');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackTopCenter('success');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackTopCenter('error');
            "
          >
            Error
          </button>
          <hr />
          Modal. Centered. Moves up. Pushes to stack top.<br />
          <script type="text/javascript">
            window.showStackModal = function showStackModal(type) {
              if (typeof window.stackModal === 'undefined') {
                window.stackModal = new PNotify.Stack({
                  dir1: 'up',
                  firstpos1: 25,
                  push: 'top',
                  modal: true,
                  maxOpen: Infinity,
                });
              }
              const opts = {
                title: 'Over Here',
                text: "Check me out. I'm in a different stack.",
                stack: window.stackModal,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [
                    PNotifyConfirm,
                    {
                      confirm: true,
                      buttons: [
                        {
                          text: 'Another',
                          primary: true,
                          click: () => showStackModal(type),
                        },
                      ],
                    },
                  ],
                ]),
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackModal('notice');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackModal('info');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackModal('success');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackModal('error');
            "
          >
            Error
          </button>
          <hr />
          Modal. Moves down, then right. Pushes to stack bottom.<br />
          <script type="text/javascript">
            window.showStackModalLeft = function showStackModalLeft(type) {
              if (typeof window.stackModalLeft === 'undefined') {
                window.stackModalLeft = new PNotify.Stack({
                  dir1: 'down',
                  dir2: 'right',
                  firstpos1: 25,
                  firstpos2: 25,
                  modal: true,
                  maxOpen: Infinity,
                });
              }
              const opts = {
                title: 'Over Here',
                text: "Check me out. I'm in a different stack.",
                stack: window.stackModalLeft,
                modules: new Map([
                  ...PNotify.defaultModules,
                  [
                    PNotifyConfirm,
                    {
                      confirm: true,
                      buttons: [
                        {
                          text: 'Another',
                          primary: true,
                          click: () => showStackModalLeft(type),
                        },
                      ],
                    },
                  ],
                ]),
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackModalLeft('notice');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackModalLeft('info');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackModalLeft('success');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackModalLeft('error');
            "
          >
            Error
          </button>
          <hr />
          Top bar style. Modeless. Moves down, then right. Pushes to stack
          top.<br />
          <script type="text/javascript">
            window.showStackBarTop = function showStackBarTop(type) {
              if (typeof window.stackBarTop === 'undefined') {
                window.stackBarTop = new PNotify.Stack({
                  modal: false,
                  dir1: 'down',
                  firstpos1: 0,
                  spacing1: 0,
                  push: 'top',
                  maxOpen: Infinity,
                });
              }
              const opts = {
                title: 'Over Here',
                text: "Check me out. I'm in a different stack.",
                addClass: 'stack-bar-top',
                shadow: false,
                width: '100%',
                stack: window.stackBarTop,
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBarTop('notice');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBarTop('info');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBarTop('success');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBarTop('error');
            "
          >
            Error
          </button>
          <br />
          This demo uses this CSS:
          <pre><code class="css">[data-pnotify].pnotify.stack-bar-top {
  width: 100%;
  border-radius: 0;
}</code></pre>
          <hr />
          Bottom bar style. Modalish. Moves up, then right. Pushes to stack
          bottom.<br />
          <script type="text/javascript">
            window.showStackBarBottom = function showStackBarBottom(type) {
              if (typeof window.stackBarBottom === 'undefined') {
                window.stackBarBottom = new PNotify.Stack({
                  dir1: 'up',
                  firstpos1: 0,
                  spacing1: 0,
                });
              }
              const opts = {
                title: 'Over Here',
                text: "Check me out. I'm in a different stack.",
                addClass: 'stack-bar-bottom',
                shadow: false,
                width: '100%',
                stack: window.stackBarBottom,
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBarBottom('notice');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBarBottom('info');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBarBottom('success');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackBarBottom('error');
            "
          >
            Error
          </button>
          <br />
          This demo uses this CSS:
          <pre><code class="css">[data-pnotify].pnotify.stack-bar-bottom {
  width: 70%;
  border-radius: 0;
}</code></pre>
          <hr />
          No stack.<br />
          <script type="text/javascript">
            window.addEventListener('DOMContentLoaded', () => {
              window.makeTooltip = function makeTooltip() {
                window.tooltip = PNotify.notice({
                  title: 'Tooltip',
                  text: "I'm not in a stack. I'm positioned like a tooltip with JavaScript.",
                  hide: false,
                  closer: false,
                  sticker: false,
                  animateSpeed: 'fast',
                  icon: 'fas fa-comment',
                  // Setting stack to null causes PNotify to ignore this notice when positioning.
                  stack: null,
                  autoOpen: false,
                  destroy: false,
                  modules: new Map([
                    ...[...PNotify.defaultModules].filter(
                      ([mod]) => mod !== PNotifyMobile
                    ),
                  ]),
                });
                // Close the notice if the user mouses over it.
                window.tooltip.on('mouseout', () => window.tooltip.close());
              };
              // I put it in a function so I could show the source easily.
              window.makeTooltip();
            });
          </script>
          <button
            class="btn btn-light my-1 source"
            onmouseover="window.tooltip.open();"
            onmousemove="window.tooltip.refs.elem.style.top = (event.clientY + 12) + 'px'; window.tooltip.refs.elem.style.left = (event.clientX + 12) + 'px';"
            onmouseout="window.tooltip.close();"
          >
            Hover Over Me
          </button>
        </div>
        <h5 class="card-header">Stack Contexts</h5>
        <div class="card-body">
          You can specify a context element for your notices to be placed in.
          <hr />
          <script type="text/javascript">
            window.showStackContext = function showStackContext(type, modal) {
              if (typeof window.stackContext === 'undefined') {
                window.stackContext = new PNotify.Stack({
                  dir1: 'down',
                  dir2: 'left',
                  firstpos1: 25,
                  firstpos2: 25,
                  context: document.getElementById('stack-context'),
                });
              }
              if (typeof window.stackContextModeless === 'undefined') {
                window.stackContextModeless = new PNotify.Stack({
                  dir1: 'down',
                  dir2: 'right',
                  firstpos1: 25,
                  firstpos2: 25,
                  context: document.getElementById('stack-context'),
                  modal: false,
                  maxOpen: Infinity,
                });
              }
              if (typeof window.stackContextModal === 'undefined') {
                window.stackContextModal = new PNotify.Stack({
                  dir1: 'down',
                  firstpos1: 25,
                  context: document.getElementById('stack-context'),
                  modal: true,
                  maxOpen: Infinity,
                });
              }
              const opts = {
                title: 'Over Here',
                text: "Check me out. I'm in a different stack.",
                stack:
                  modal === 'ish'
                    ? window.stackContext
                    : modal
                    ? window.stackContextModal
                    : window.stackContextModeless,
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          Modalish (the default):<br />
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('notice', 'ish');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('info', 'ish');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('success', 'ish');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('error', 'ish');
            "
          >
            Error
          </button>
          <br />
          Modeless:<br />
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('notice', false);
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('info', false);
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('success', false);
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('error', false);
            "
          >
            Error
          </button>
          <br />
          Modal:<br />
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('notice', true);
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('info', true);
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('success', true);
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showStackContext('error', true);
            "
          >
            Error
          </button>
          <br />
          <script type="text/javascript">
            window.showUnpositionedStack = function showUnpositionedStack(
              type
            ) {
              if (typeof window.unpositionedStack === 'undefined') {
                window.unpositionedStack = new PNotify.Stack({
                  maxOpen: Infinity,
                  modal: false,
                  positioned: false,
                  context: document.getElementById('unpositioned-context'),
                });
              }
              const opts = {
                title: 'Over Here',
                text: "I'm in an unpositioned stack. That means I'm not taken out of the flow, and my position is determined by the browser.",
                width: '100%',
                shadow: false,
                stack: window.unpositionedStack,
              };
              switch (type) {
                case 'error':
                  opts.title = 'Oh No';
                  opts.text = 'Watch out for that water tower!';
                  opts.type = 'error';
                  break;
                case 'info':
                  opts.title = 'Breaking News';
                  opts.text = 'Have you met Ted?';
                  opts.type = 'info';
                  break;
                case 'success':
                  opts.title = 'Good News Everyone';
                  opts.text =
                    "I've invented a device that bites shiny metal asses.";
                  opts.type = 'success';
                  break;
              }
              PNotify.alert(opts);
            };
          </script>
          Unpositioned Stack:<br />
          <button
            class="btn btn-light my-1 source"
            onclick="
              showUnpositionedStack('notice');
            "
          >
            Notice
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showUnpositionedStack('info');
            "
          >
            Info
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showUnpositionedStack('success');
            "
          >
            Success
          </button>
          <button
            class="btn btn-light my-1 source"
            onclick="
              showUnpositionedStack('error');
            "
          >
            Error
          </button>
          <div class="row justify-content-md-center mt-3">
            <div class="col-md-10">
              <div class="card">
                <div
                  id="stack-context"
                  class="card-body"
                  style="height: 350px; position: relative; overflow: auto"
                >
                  <div class="my-3">
                    <h3>Stack Context</h3>
                    <hr />
                  </div>
                  <div id="unpositioned-context"></div>
                  <p>
                    I'm the stack context where notices will be placed. I'm
                    position: relative, so the notices will be positioned
                    relative to me. My overflow is set to auto, so the notices
                    won't show beyond my borders.
                  </p>
                  <p style="text-align: center">
                    <img
                      alt="Happy face"
                      src="includes/le_happy_face_by_luchocas.png"
                    />
                  </p>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="card-footer">
          <p class="alert alert-warning">
            <i class="fas fa-exclamation-triangle"></i> You can't just pass in a
            new stack if you want multiple notices to line up. You need to
            assign the stack to a variable and pass that. This is because
            PNotify will use that object to store the notices that go into it.
          </p>
          <div class="row">
            <div class="col-md-6">
              <div class="card border-danger mt-3">
                <h6 class="card-header text-light bg-danger">
                  Bad - Notices will overlap.
                </h6>
                <div class="card-body">
                  <pre><code class="js">PNotify.notice({
  text: 'Notice 1.',
  stack: new PNotify.Stack({dir1: 'down', firstpos1: 25})
});
PNotify.notice({
  text: 'Notice 2.',
  stack: new PNotify.Stack({dir1: 'down', firstpos1: 25})
});</code></pre>
                </div>
              </div>
            </div>
            <div class="col-md-6">
              <div class="card border-success mt-3">
                <h6 class="card-header text-light bg-success">
                  Good - Notices will flow in line.
                </h6>
                <div class="card-body text-success">
                  <pre><code class="js">const myStack = new PNotify.Stack({dir1: 'down', firstpos1: 25});
PNotify.notice({
  text: 'Notice 1.',
  stack: myStack
});
PNotify.notice({
  text: 'Notice 2.',
  stack: myStack
});</code></pre>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div
      id="comments"
      class="container page-section"
      style="margin-bottom: 20px"
    >
      <div class="my-3">
        <h2>Comments</h2>
        <hr />
      </div>
      <div id="commentLoader" style="text-align: center">
        <button
          class="btn btn-primary"
          onclick="
            loadDisqus();
            (node => node.parentNode.removeChild(node))(document.getElementById('commentLoader'));
          "
        >
          Load Comments
        </button>
      </div>
      <div id="disqus_thread"></div>
      <a href="https://disqus.com" class="dsq-brlink"
        >comments powered by <span class="logo-disqus">Disqus</span></a
      >
      <script type="text/javascript">
        var disqus_config = function () {
          this.page.url = 'https://sciactive.com/pnotify/';
          this.page.identifier = 'demo';
        };
        function loadDisqus() {
          // DON'T EDIT BELOW THIS LINE
          var d = document,
            s = d.createElement('script');
          s.src = 'https://pnotify.disqus.com/embed.js';
          s.setAttribute('data-timestamp', +new Date());
          (d.head || d.body).appendChild(s);
        }
      </script>
    </div>
    <p id="copyright">&copy; 2011-2020 Hunter Perrin. All Rights Reserved.</p>

    <script type="text/javascript">
      window.addEventListener('DOMContentLoaded', () => {
        // ---
        // This creates all those source code view buttons.
        // ---
        const makeSourceButton = (button) => {
          button.classList.remove('source');
          // Wrap the button in a container.
          const contain = document.createElement('div');
          contain.classList.add('btn-group');
          button.parentNode.insertBefore(contain, button);
          contain.appendChild(button);

          const sourceButton = document.createElement('button');
          button.setAttribute('type', 'button');
          const icon = document.createElement('i');
          icon.classList.add('fas', 'fa-code', 'fa-sm');
          sourceButton.appendChild(icon);
          sourceButton.classList.add(...button.classList.values());
          contain.appendChild(sourceButton);

          sourceButton.addEventListener('click', (e) => {
            let text = '';

            function addText(more) {
              text += (text ? '\n\n' : '') + more;
            }

            if (button.hasAttribute('onclick')) {
              addText(button.attributes.onclick.value);
            }
            if (button.hasAttribute('onmouseover')) {
              addText('// Mouse Over:\n' + button.attributes.onmouseover.value);
            }
            if (button.hasAttribute('onmousemove')) {
              addText('// Mouse Move:\n' + button.attributes.onmousemove.value);
            }
            if (button.hasAttribute('onmouseout')) {
              addText('// Mouse Out:\n' + button.attributes.onmouseout.value);
            }

            const sourceElement = document.createElement('div');

            PNotify.info({
              title: button.textContent.trim() + ' - Source',
              text: sourceElement,
              icon: 'fas fa-code',
              hide: false,
              sticker: false,
              destroy: true,
              width: '80vw',
              maxTextHeight: null,
              stack: new PNotify.Stack({
                modal: true,
                overlayClosesPinned: true,
              }),
            });

            addPrettyCode(text, sourceElement);

            // Check if the code is calling a function. Include that function.
            const match = text.match(
              /^\s*(?:window\.)?(\w+)\s*\([^\)]*\);\s*$/
            );
            if (match) {
              const fName = match[1];
              addPrettyCode(window[fName].toString(), sourceElement);
            }

            // Check if this is the tooltip button. Include the tooltip function.
            if (text.match(/tooltip\.open\(\);/)) {
              addPrettyCode(window.makeTooltip.toString(), sourceElement);
            }
          });
        };

        const addPrettyCode = (code, where) => {
          const codeBlock = document.createElement('code');
          codeBlock.style.maxHeight = '200px';
          codeBlock.style.overflowY = 'auto';
          codeBlock.classList.add('js');
          codeBlock.textContent = window.beautifier.js(code, {
            indent_size: 2,
          });
          const pre = document.createElement('pre');
          pre.appendChild(codeBlock);
          where.appendChild(pre);
          window.hljs.highlightBlock(codeBlock);
        };

        document.body.addEventListener('mouseenter', (e) => {
          if (e.target.classList.contains('source')) {
            makeSourceButton(e.target);
          }
        });

        document.body.addEventListener('click', (e) => {
          if (e.target.classList.contains('source')) {
            makeSourceButton(e.target);
          }
        });

        document
          .querySelectorAll('.source')
          .forEach((el) => makeSourceButton(el));
      });

      window.hljs.initHighlightingOnLoad(); // Format source in help.
    </script>

    <!-- prettier-ignore -->
    <script>
      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

      ga('create', 'UA-49382439-1', 'sciactive.com');
      ga('send', 'pageview');
    </script>
  </body>
</html>
